<template>
  <Title>图片前后色彩密度展示</Title>
  <ShowBox>
    <!-- 图片选择 -->
    <el-upload
      action="http://localhost:8080/upload"
      v-model:file-list="fileList"
      :auto-upload="false"
      class="upload-demo"
      accept=".jpg,.jpeg,.png"
      :on-change="handleImageChange"
    >
      <el-button type="primary">选择图片</el-button>
      <template #tip>
        <div class="el-upload__tip">请选择一张图片（jpg/png 格式）</div>
      </template>
    </el-upload>
    <div v-if="selectedImage" class="preview">
      <p>已选择图片：</p>
      <img :src="selectedImage" alt="预览图片" class="preview-image" />
    </div>

    <!-- 操作按钮 -->
    <div class="button-group">
      <el-button type="success" @click="processImage">处理图片</el-button>
    </div>

    <!-- 结果展示 -->
    <div v-if="result" class="result">
      <p>图片前色彩密度 PLY 文件：</p>
      <div ref="beforePlyContainer" class="ply-container"></div>

      <p>图片后色彩密度 PLY 文件：</p>
      <div ref="afterPlyContainer" class="ply-container"></div>
    </div>

    <!-- 展示 @/assets/cache.ply 文件 -->
    <div class="cache-ply">
      <p>缓存 PLY 文件：</p>
      <div ref="cachePlyContainer" class="ply-container"></div>
    </div>
  </ShowBox>
</template>

<script setup>
import ShowBox from '@/components/ShowBox.vue'
import Title from '@/components/Title.vue'
import { ref, onMounted, onBeforeUnmount } from 'vue'
import { ElMessage } from 'element-plus'
import axios from 'axios'
import * as THREE from 'three'
import { PLYLoader } from 'three/examples/jsm/loaders/PLYLoader'

// 已选择的图片文件
const fileList = ref([])
// 图片路径（用于预览）
const selectedImage = ref(null)
// 后端返回的结果
const result = ref(null)
// PLY 容器
const beforePlyContainer = ref(null)
const afterPlyContainer = ref(null)
const cachePlyContainer = ref(null)

// 处理图片选择
const handleImageChange = (file) => {
  selectedImage.value = URL.createObjectURL(file.raw)
}

// 调用后端处理图片
const processImage = async () => {
  if (!selectedImage.value) {
    ElMessage.error('请先选择图片！')
    return
  }
  try {
    const response = await axios.post('http://localhost:8080/process', {
      imagePath: selectedImage.value,
    })
    if (response.data.success) {
      result.value = {
        beforePlyPath: response.data.beforePlyPath,
        afterPlyPath: response.data.afterPlyPath,
      }
      loadPlyFiles()
      ElMessage.success('图片处理成功！')
    } else {
      ElMessage.error('图片处理失败，请检查后端逻辑！')
    }
  } catch (error) {
    console.error(error)
    ElMessage.error('请求失败，请检查后端服务！')
  }
}

// 加载 PLY 文件
const loadPlyFiles = () => {
  if (result.value) {
    loadPly(result.value.beforePlyPath, beforePlyContainer.value)
    loadPly(result.value.afterPlyPath, afterPlyContainer.value)
  }
}

// 加载单个 PLY 文件
const loadPly = (url, container) => {
  const scene = new THREE.Scene()
  const camera = new THREE.PerspectiveCamera(75, container.clientWidth / container.clientHeight, 0.1, 1000)
  const renderer = new THREE.WebGLRenderer()
  renderer.setSize(container.clientWidth, container.clientHeight)
  container.appendChild(renderer.domElement)

  const loader = new PLYLoader()
  loader.load(url, (geometry) => {
    const material = new THREE.PointsMaterial({ color: 0xffffff, size: 0.01 })
    const points = new THREE.Points(geometry, material)
    scene.add(points)

    camera.position.z = 2

    const animate = () => {
      requestAnimationFrame(animate)
      renderer.render(scene, camera)
    }

    animate()
  })
}

// 加载缓存 PLY 文件
const loadCachePly = () => {
  const url = new URL('@/assets/cache.ply', import.meta.url).href
  loadPly(url, cachePlyContainer.value)
}

// 组件挂载时加载缓存 PLY 文件
onMounted(() => {
  loadCachePly()
  if (result.value) {
    loadPlyFiles()
  }
})

// 组件卸载时清理资源
onBeforeUnmount(() => {
  beforePlyContainer.value.innerHTML = ''
  afterPlyContainer.value.innerHTML = ''
  cachePlyContainer.value.innerHTML = ''
})
</script>

<style scoped>
.preview {
  margin-top: 10px;
}
.preview-image {
  max-width: 300px;
  border: 1px solid #ddd;
  border-radius: 5px;
  margin-top: 10px;
}
.button-group {
  margin: 20px 0;
}
.result {
  margin-top: 20px;
}
.ply-container {
  width: 100%;
  height: 300px;
  border: 1px solid #ddd;
  border-radius: 5px;
  margin-top: 10px;
}
.cache-ply {
  margin-top: 20px;
}
</style>